package com.tgjorgoski.sidekicknotes.browser;

import java.awt.Dimension;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.filechooser.FileSystemView;

import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.demo.HTMLDocument;
import org.apache.lucene.demo.html.HTMLParser;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;

import com.tgjorgoski.window.HTMLView;
import com.tgjorgoski.window.Session;

public class BrowserPanel extends JScrollPane implements ComponentListener {
	List<File> filesL;
	FileSystemView fsv;
	AbstractFileBrowserPanel panel;
	File folder;
	
	SearchBrowserSubPanel panelListSearch = new SearchBrowserSubPanel();
	BrowserSubPanel panelListNormal = new BrowserSubPanel();

	public BrowserPanel() {
		this(null);
	}
	public BrowserPanel(File folder) {
		setBorder(null);
		
		fsv = FileSystemView.getFileSystemView();
		
		filesL = new ArrayList<File>();

		if (folder==null) {
			folder = fsv.getHomeDirectory();
		}
		this.folder=folder;

		panel=panelListNormal;
		setSubpanel(panelListNormal);
		getViewport().addComponentListener(this);
	}
	
	public void setSubpanel(AbstractFileBrowserPanel subPanel) {
		if (subPanel.isVertical()) {
			setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
			setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
		} else {
			setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
			setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
		}
		setViewportView(subPanel.getViewportView());
		subPanel.setBrowserPanel(this);
		panel=subPanel;
	}
	
	public File getFolder() {
		return folder;
	}
	
	public boolean focusOnFile(File file) {
		return panel.focusOnFile(file);
	}
	
	public void refreshToAllFiles() {
		setSubpanel(panelListNormal);
		File[] files = fsv.getFiles(folder, true);
		filesL.clear();
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			if (!file.isDirectory()) {
				filesL.add(file);
			}
		}
		panel.setFileList(filesL, null);
	}
	
	private String lastValidSearch="";
	public int doSearch(String userQueryString) {
		int size=0;
		try {
			IndexSearcher iSearcher = new IndexSearcher(Session.getIndexFolder());
			Analyzer analyzer = new StandardAnalyzer();
			QueryParser qP = new QueryParser("contents", analyzer);
			Query query = qP.parse(userQueryString);
			Query rewQuery=query.rewrite(iSearcher.getIndexReader());
			QueryScorer queryScorer = new QueryScorer(rewQuery);
			Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter(), queryScorer);
			highlighter.setTextFragmenter(new Fragmenter() {
				int lastEnd;
				int lastTokenEnd;
				private String text;
				private int countLength=0;
				
				public void start(String text) {
					lastEnd=0;
					lastTokenEnd=0;
					countLength=0;
					this.text=text;
				}
				
				public boolean isNewFragment(Token token) {
					int length = token.startOffset()-lastEnd;
					
					//check what we have between the lastEnd and this start
					boolean newLine=false;
					boolean sentenceEnd = false;
					for (int i = lastTokenEnd; i < token.startOffset(); i++) {
						char thisChar = text.charAt(i);
						if (thisChar=='\n') {
							newLine=true;
						}
						if (thisChar=='.') {
							sentenceEnd=true;
						}
					}
					
					boolean isNew = false;
					
					if (newLine && countLength>20) isNew=true;
					//if (sentenceEnd && length>100) isNew=true;
					if (countLength>100) isNew=true;
					if (!isNew) {
						lastTokenEnd = token.endOffset();
						countLength+=token.endOffset()-token.startOffset();
					} else {
						lastEnd=lastTokenEnd;
						countLength=token.endOffset()-token.startOffset();
					}
					
					return isNew;
				}
			});
			
			Hits hits = iSearcher.search(query);
			if (hits.length()==0) {
				lastValidSearch="";
				return 0;
			}
			List<File> paths = new ArrayList<File>();
			List<String> snippets = new ArrayList<String>();
			for (int i=0; i<hits.length(); i++) {
				Document doc = hits.doc(i);
				String path = doc.get(HTMLDocument.FIELD_PATH);
				File file = new File(Session.getHomeFolder(), path);
				if (!paths.contains(file)) paths.add(file);
				
				FileInputStream fis = new FileInputStream(file);
				HTMLParser parser = new HTMLParser(fis);
				Reader r = parser.getReader();
				StringBuffer sbuf = new StringBuffer();
				for(int charc = r.read(); charc!=-1; charc=r.read()) {
					sbuf.append((char)charc);
				}
				
				
				TokenStream tokenStream = analyzer.tokenStream(HTMLDocument.FIELD_CONTENTS, new StringReader(sbuf.toString()));
				
				String result = highlighter.getBestFragments(tokenStream, sbuf.toString(), 4, " <b>...</b> ");
				snippets.add(result);
			}
			size = paths.size();
			lastValidSearch=userQueryString;
			
			setSubpanel(panelListSearch);
			panel.setFileList(paths, snippets);
		} catch (Exception exc) {
			lastValidSearch="";
			return 0;
		}
		return size;
	}
	
	public void setFocusOnBrowser() {
		//FIXME:Doesn't work?
		panel.focusOnFirstFile();
	}
	
	public void componentHidden(ComponentEvent e) {
	}
	public void componentMoved(ComponentEvent e) {
	}
	public void componentResized(ComponentEvent e) {
		if (e.getComponent() instanceof JViewport) {
			JViewport vp = (JViewport)e.getComponent();
			int height = vp.getHeight();
			int width = vp.getWidth();
			Dimension dim = panel.getViewportView().getSize();
			if (panel.isVertical())
				dim.width=width;
			else
				dim.height=height;
			panel.getViewportView().setSize(dim);
			panel.refreshView();
		}
	}
	public void componentShown(ComponentEvent e) {
	}
}
